﻿using System;
using Framework.Core;
using Framework.Core.Io;

namespace Framework.Remoting.Conventions
{
    public class WcfServiceInfoFactory : IWcfServiceInfoFactory
    {
        private IConfigurationManagerAdapter ConfigurationManagerAdapter { get; set; }
        private IBindingFactory BindingFactory { get; set; }
        private IProtocolFactory ProtocolFactory { get; set; }

        public WcfServiceInfoFactory(IConfigurationManagerAdapter configurationManagerAdapter,
                                     IBindingFactory bindingFactory, IProtocolFactory protocolFactory)
        {
            ConfigurationManagerAdapter = configurationManagerAdapter;
            BindingFactory = bindingFactory;
            ProtocolFactory = protocolFactory;
        }
        
        public WcfServiceInfo Create(EnvMode envMode, Type contractType)
        {
            var config =
                ConfigurationManagerAdapter.GetSection<IEnvironments, HostConfiguration>().GetEnvironment(envMode);
            var binding = BindingFactory.Create(config.BindingType);
            var protocol = ProtocolFactory.Create(binding);
            var uri = GetUri(protocol, envMode, config.Host, config.Port, contractType);

            return new WcfServiceInfo(binding, uri);
        }

        public WcfServiceInfo Create<TContract>(EnvMode envMode)
        {
            return Create(envMode, typeof (TContract));
        }

        private static Uri GetUri(string protocol, EnvMode envMode, string hostName, int portNumber, Type contractType)
        {
            var contractName = contractType.FullName;
            var address = string.Format("{0}://{1}:{2}/{3}/{4}/", protocol, hostName, portNumber, envMode, contractName);
            return new Uri(address);
        }
    }
}